home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / olereg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  15.7 KB  |  542 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #include <shellapi.h>
  13.  
  14. #ifdef AFX_OLE4_SEG
  15. #pragma code_seg(AFX_OLE4_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. #define new DEBUG_NEW
  24.  
  25. // from docmgr.cpp
  26. extern BOOL AFXAPI _AfxDeleteRegKey(LPCTSTR lpszKey);
  27.  
  28.  
  29. //////////////////////////////////////////////////////////////////////////////
  30. // data for UpdateRegistry functionality
  31.  
  32. // %1 - class ID
  33. // %2 - class name
  34. // %3 - SFN executable path
  35. // %4 - short type name
  36. // %5 - long type name
  37. // %6 - long application name
  38. // %7 - icon index
  39. // %8 - Creator(xxxxxxxx) [mac-only]
  40. // %8 - File extension Description [non-mac only]
  41. // %9 - (not used yet) [mac-only]
  42. // %9 - File extension *.TLA [non-mac only]
  43. // %A - (not used yet)
  44. #define NUM_REG_VARS 10
  45.  
  46. class CAfxOleSymbolTable
  47. {
  48. protected:
  49.     LPTSTR* m_strEntries;
  50.     int m_nEntries;
  51.  
  52. public:
  53.     CAfxOleSymbolTable(int nEntries);
  54.     ~CAfxOleSymbolTable();
  55.  
  56.     LPCTSTR* GetArray() { return (LPCTSTR*) m_strEntries; }
  57.     LPCTSTR GetAt(int nIndex) const;
  58.     void SetAt(int nIndex, LPCTSTR pstr);
  59.     LPCTSTR operator[](int nIndex) const { return GetAt(nIndex); }
  60. };
  61.  
  62. CAfxOleSymbolTable::CAfxOleSymbolTable(int nEntries)
  63. {
  64.     m_strEntries = new LPTSTR[nEntries];
  65.     memset(m_strEntries, 0, sizeof(LPTSTR) * nEntries);
  66.     m_nEntries = nEntries;
  67. }
  68.  
  69. CAfxOleSymbolTable::~CAfxOleSymbolTable()
  70. {
  71.     int nIndex;
  72.     for (nIndex = 0; nIndex < m_nEntries; nIndex++)
  73.         free(m_strEntries[nIndex]);
  74.     delete [] m_strEntries;
  75. }
  76.  
  77. void CAfxOleSymbolTable::SetAt(int nIndex, LPCTSTR pstr)
  78. {
  79.     ASSERT(nIndex < m_nEntries && nIndex >= 0);
  80.  
  81.     free(m_strEntries[nIndex]);
  82.     m_strEntries[nIndex] = pstr ? _tcsdup(pstr) : NULL;
  83. }
  84.  
  85. LPCTSTR CAfxOleSymbolTable::GetAt(int nIndex) const
  86. {
  87.     if (nIndex < m_nEntries || nIndex < 0)
  88.         return m_strEntries[nIndex];
  89.     else
  90.         return NULL;
  91. }
  92.  
  93. static const TCHAR sz00[] = _T("%2\0") _T("%5");
  94. static const TCHAR sz01[] = _T("%2\\CLSID\0") _T("%1");
  95. static const TCHAR sz02[] = _T("%2\\Insertable\0") _T("");
  96. static const TCHAR sz03[] = _T("%2\\protocol\\StdFileEditing\\verb\\0\0") _T("&Edit");
  97. static const TCHAR sz04[] = _T("%2\\protocol\\StdFileEditing\\server\0") _T("%3");
  98. static const TCHAR sz05[] = _T("CLSID\\%1\0") _T("%5");
  99. static const TCHAR sz06[] = _T("CLSID\\%1\\ProgID\0") _T("%2");
  100. static const TCHAR sz07[] = _T("CLSID\\%1\\InprocHandler32\0") _T("ole32.dll");
  101. static const TCHAR sz08[] = _T("CLSID\\%1\\LocalServer32\0") _T("%3");
  102. static const TCHAR sz09[] = _T("CLSID\\%1\\Verb\\0\0") _T("&Edit,0,2");
  103. static const TCHAR sz10[] = _T("CLSID\\%1\\Verb\\1\0") _T("&Open,0,2");
  104. static const TCHAR sz11[] = _T("CLSID\\%1\\Insertable\0") _T("");
  105. static const TCHAR sz12[] = _T("CLSID\\%1\\AuxUserType\\2\0") _T("%4");
  106. static const TCHAR sz13[] = _T("CLSID\\%1\\AuxUserType\\3\0") _T("%6");
  107. static const TCHAR sz14[] = _T("CLSID\\%1\\DefaultIcon\0") _T("%3,%7");
  108. static const TCHAR sz15[] = _T("CLSID\\%1\\MiscStatus\0") _T("32");
  109. static const TCHAR sz16[] = _T("\0") _T("");
  110. static const TCHAR sz17[] = _T("CLSID\\%1\\InProcServer32\0") _T("%3");
  111. static const TCHAR sz18[] = _T("CLSID\\%1\\DocObject\0" _T("0")); // CLSIDDocObject
  112. static const TCHAR sz19[] = _T("%2\\DocObject\0" _T("0")); // ProgIDDocObject
  113. static const TCHAR sz20[] = _T("CLSID\\%1\\Printable\0"); // szPrintable
  114. static const TCHAR sz21[] = _T("CLSID\\%1\\DefaultExtension\0%9, %8"); // szDefaultExt
  115.  
  116. // registration for OAT_INPLACE_SERVER
  117. static const LPCTSTR rglpszInPlaceRegister[] =
  118. {
  119.     sz00, sz02, sz03, sz05, sz09, sz10, sz11, sz12,
  120.     sz13, sz15,
  121.     NULL
  122. };
  123.  
  124. // registration for OAT_SERVER
  125. static const LPCTSTR rglpszServerRegister[] =
  126. {
  127.     sz00, sz02, sz03, sz05, sz09, sz11, sz12,
  128.     sz13, sz15,
  129.     NULL
  130. };
  131.  
  132. // registration for OAT_DOC_OBJECT_SERVER
  133. static const LPCTSTR rglpszDocObjectRegister[] =
  134. {
  135.     sz00, sz02, sz03, sz05, sz09, sz10, sz11, sz12,
  136.     sz13, sz15, sz18, sz19, sz20,
  137.     NULL
  138. };
  139.  
  140. // overwrite entries for OAT_SERVER & OAT_INPLACE_SERVER
  141. static const LPCTSTR rglpszServerOverwrite[] =
  142. {
  143.     sz01, sz04, sz06, sz07, sz08, sz14, NULL
  144. };
  145. // overwrite entries for OAT_SERVER & OAT_INPLACE_SERVER (dll)
  146. static const LPCTSTR rglpszServerOverwriteDLL[] =
  147. {
  148.     sz01, sz04, sz06,
  149.     sz17,
  150.     sz14,
  151.     NULL
  152. };
  153.  
  154. // registration for OAT_CONTAINER
  155. static const LPCTSTR rglpszContainerRegister[] =
  156. {
  157.     sz00, sz05, NULL
  158. };
  159. // overwrite entries for OAT_CONTAINER
  160. static const LPCTSTR rglpszContainerOverwrite[] =
  161. {
  162.     sz01, sz06, sz07, sz08, sz14, NULL
  163. };
  164.  
  165. // registration for OAT_DISPATCH_OBJECT
  166. static const LPCTSTR rglpszDispatchRegister[] =
  167. {
  168.     sz00, sz05, NULL
  169. };
  170. // overwrite entries for OAT_DISPATCH_OBJECT
  171. static const LPCTSTR rglpszDispatchOverwrite[] =
  172. {
  173.     sz01, sz06, sz07, sz08, NULL
  174. };
  175. // overwrite entries for OAT_DISPATCH_OBJECT (dll)
  176. static const LPCTSTR rglpszDispatchOverwriteDLL[] =
  177. {
  178.     sz01, sz06,
  179.     sz17,
  180.     NULL
  181. };
  182.  
  183. // overwrite entries for OAT_DOC_OBJECT_SERVER
  184. static const LPCTSTR rglpszDocObjectOverwrite[] =
  185. {
  186.     sz01, sz04, sz06, sz07, sz08, sz14, sz21,
  187.     NULL
  188. };
  189.  
  190. struct STANDARD_ENTRY
  191. {
  192.     const LPCTSTR* rglpszRegister;
  193.     const LPCTSTR* rglpszOverwrite;
  194. };
  195.  
  196. static const STANDARD_ENTRY rgStdEntries[] =
  197. {
  198.     { rglpszInPlaceRegister, rglpszServerOverwrite },
  199.     { rglpszServerRegister, rglpszServerOverwrite },
  200.     { rglpszContainerRegister, rglpszContainerOverwrite },
  201.     { rglpszDispatchRegister, rglpszDispatchOverwrite },
  202.     { rglpszDocObjectRegister, rglpszDocObjectOverwrite },
  203. };
  204.  
  205. static const STANDARD_ENTRY rgStdEntriesDLL[] =
  206. {
  207.     { rglpszInPlaceRegister, rglpszServerOverwriteDLL },
  208.     { rglpszServerRegister, rglpszServerOverwriteDLL },
  209.     { rglpszContainerRegister, rglpszContainerOverwrite },
  210.     { rglpszDispatchRegister, rglpszDispatchOverwriteDLL },
  211.     { rglpszDocObjectRegister, rglpszDocObjectOverwrite },
  212. };
  213.  
  214. /////////////////////////////////////////////////////////////////////////////
  215. // Special registration for apps that wish not to use REGLOAD
  216.  
  217. BOOL AFXAPI AfxOleRegisterServerClassCompat(
  218.     REFCLSID clsid, LPCTSTR lpszClassName,
  219.     LPCTSTR lpszShortTypeName, LPCTSTR lpszLongTypeName,
  220.     OLE_APPTYPE nAppType, LPCTSTR* rglpszRegister, LPCTSTR* rglpszOverwrite)
  221. {
  222.     return AfxOleRegisterServerClass(clsid, lpszClassName, lpszShortTypeName,
  223.         lpszLongTypeName, nAppType, rglpszRegister, rglpszOverwrite);
  224. }
  225.  
  226. AFX_STATIC BOOL AFXAPI _AfxOleMakeSymbolTable(CAfxOleSymbolTable& refTable,
  227.     REFCLSID clsid, LPCTSTR lpszClassName, LPCTSTR lpszShortTypeName,
  228.     LPCTSTR lpszLongTypeName, int nIconIndex, 
  229.     LPCTSTR lpszFilterName, LPCTSTR lpszFilterExt)
  230. {
  231.     // 0 - class ID
  232.     // 1 - class name
  233.     // 2 - SFN executable path
  234.     // 3 - short type name
  235.     // 4 - long type name
  236.     // 5 - long application name
  237.     // 6 - icon index
  238.     // 7 - Creator(xxxxxxxx) [Mac only]
  239.     // 8 - Creator(xxxxxxxx) [mac-only]
  240.     // 9 - Filter description
  241.  
  242.     // convert the CLSID to a string
  243.     LPTSTR lpszClassID;
  244.     LPOLESTR lpOleStr;
  245.     ::StringFromCLSID(clsid, &lpOleStr);
  246.     lpszClassID = TASKSTRINGOLE2T(lpOleStr);
  247.     if (lpszClassID == NULL)
  248.     {
  249.         TRACE0("Warning: StringFromCLSID failed in AfxOleRegisterServerName --\n");
  250.         TRACE0("\tperhaps AfxOleInit() has not been called.\n");
  251.         return FALSE;
  252.     }
  253.     refTable.SetAt(0, lpszClassID);
  254.     refTable.SetAt(1, lpszClassName);
  255.  
  256.     // free memory for class ID
  257.     ASSERT(lpszClassID != NULL);
  258.     CoTaskMemFree(lpszClassID);
  259.  
  260.     // get path name to server
  261.     CString strPathName;
  262.     AfxGetModuleShortFileName(AfxGetInstanceHandle(), strPathName);
  263.     refTable.SetAt(2, strPathName);
  264.  
  265.     // fill in rest of symbols
  266.     refTable.SetAt(3, lpszShortTypeName);
  267.     refTable.SetAt(4, lpszLongTypeName);
  268.     refTable.SetAt(5, AfxGetAppName()); // will usually be long, readable name
  269.  
  270.     CString strIconIndex;
  271.     if (nIconIndex != 0)
  272.     {
  273. #if defined(_WIN32_WCE)
  274.         HICON hIcon = (HICON)::ExtractIconEx(strPathName,nIconIndex,NULL,NULL,1);
  275. #else // _WIN32_WCE
  276.         HICON hIcon = ::ExtractIcon(AfxGetInstanceHandle(), strPathName, nIconIndex);
  277. #endif // _WIN32_WCE
  278.         if (hIcon != NULL)
  279.             DestroyIcon(hIcon);
  280.         else
  281.             nIconIndex = 0; // couldn't find specified icon so use default
  282.     }
  283.     strIconIndex.Format(_T("%d"), nIconIndex);
  284.     refTable.SetAt(6, strIconIndex);
  285.  
  286.     refTable.SetAt(7, lpszFilterName);
  287.  
  288.     CString strFileExtension;
  289.     if (lpszFilterExt != NULL && *lpszFilterExt != 0)
  290.     {
  291.         // use file extension provided
  292.         strFileExtension = lpszFilterExt;
  293.     }
  294.     else
  295.     {
  296.         // otherwise, try to find the extension from the description
  297.  
  298.         // parse the actual extension (eg "*.TLA") from the
  299.         // filter name (eg, "Three Letter Acronym Files (*.TLA)")
  300.  
  301.         strFileExtension = lpszFilterName;
  302.         int nBeginning = strFileExtension.Find('(');
  303.         if (nBeginning == -1)
  304.             strFileExtension.Empty();
  305.         else
  306.         {
  307.             strFileExtension = strFileExtension.Mid(1+nBeginning);
  308.             nBeginning = strFileExtension.Find('.');
  309.             if (nBeginning == -1)
  310.                 strFileExtension.Empty();
  311.             else
  312.             {
  313.                 strFileExtension = strFileExtension.Mid(nBeginning);
  314.  
  315.                 int nEnd = strFileExtension.Find(')');
  316.                 if (nEnd == -1)
  317.                     strFileExtension.Empty();
  318.                 else
  319.                     strFileExtension = strFileExtension.Left(nEnd);
  320.             }
  321.         }
  322.     }
  323.     refTable.SetAt(8, strFileExtension);
  324.     return TRUE;
  325. }
  326.  
  327. BOOL AFXAPI AfxOleRegisterServerClass(
  328.     REFCLSID clsid, LPCTSTR lpszClassName, LPCTSTR lpszShortTypeName,
  329.     LPCTSTR lpszLongTypeName, OLE_APPTYPE nAppType, LPCTSTR* rglpszRegister,
  330.     LPCTSTR* rglpszOverwrite, int nIconIndex,
  331.     LPCTSTR lpszFilterName)
  332. {
  333.     return AfxOleRegisterServerClass(clsid, lpszClassName, lpszShortTypeName,
  334.         lpszLongTypeName, nAppType, rglpszRegister, rglpszOverwrite, nIconIndex,
  335.         lpszFilterName, NULL);
  336. }
  337.  
  338.  
  339. BOOL AFXAPI AfxOleRegisterServerClass(
  340.     REFCLSID clsid, LPCTSTR lpszClassName, LPCTSTR lpszShortTypeName,
  341.     LPCTSTR lpszLongTypeName, OLE_APPTYPE nAppType, LPCTSTR* rglpszRegister,
  342.     LPCTSTR* rglpszOverwrite, int nIconIndex,
  343.     LPCTSTR lpszFilterName, LPCTSTR lpszFilterExt)
  344. {
  345.     ASSERT(AfxIsValidString(lpszClassName));
  346.     ASSERT(AfxIsValidString(lpszShortTypeName));
  347.     ASSERT(*lpszShortTypeName != 0);
  348.     ASSERT(AfxIsValidString(lpszLongTypeName));
  349.     ASSERT(*lpszLongTypeName != 0);
  350.     ASSERT(nAppType == OAT_INPLACE_SERVER || nAppType == OAT_SERVER ||
  351.         nAppType == OAT_CONTAINER || nAppType == OAT_DISPATCH_OBJECT ||
  352.         nAppType == OAT_DOC_OBJECT_SERVER);
  353.     ASSERT(nAppType >= 0 && nAppType < _countof(rgStdEntries));
  354.  
  355.     // use standard registration entries if non given
  356.     if (rglpszRegister == NULL)
  357.         rglpszRegister = (LPCTSTR*)rgStdEntries[nAppType].rglpszRegister;
  358.     if (rglpszOverwrite == NULL)
  359.     {
  360.         // DLL contexts have special strings
  361.         if (!afxContextIsDLL)
  362.             rglpszOverwrite = (LPCTSTR*)rgStdEntries[nAppType].rglpszOverwrite;
  363.         else
  364.             rglpszOverwrite = (LPCTSTR*)rgStdEntriesDLL[nAppType].rglpszOverwrite;
  365.     }
  366.  
  367.     CAfxOleSymbolTable table(NUM_REG_VARS);
  368.  
  369.     if (!_AfxOleMakeSymbolTable(table, clsid, lpszClassName,
  370.                 lpszShortTypeName, lpszLongTypeName,
  371.                 nIconIndex, lpszFilterName, lpszFilterExt))
  372.     {
  373.         return FALSE;
  374.     }
  375.  
  376.     // protect against registering an invalid DocObject server
  377.     ASSERT(nAppType != OAT_DOC_OBJECT_SERVER ||
  378.         (lstrlen(table.GetAt(8)) != 0 && lstrcmp(table.GetAt(8), _T(".*")) != 0));
  379.  
  380.     // update the registry with helper function
  381.     BOOL bResult;
  382.     bResult = AfxOleRegisterHelper(rglpszRegister, table.GetArray(),
  383.         NUM_REG_VARS, FALSE);
  384.     if (bResult && rglpszOverwrite != NULL)
  385.     {
  386.         bResult = AfxOleRegisterHelper(rglpszOverwrite, table.GetArray(),
  387.             NUM_REG_VARS, TRUE);
  388.     }
  389.  
  390.     // free memory for class ID
  391.     return bResult;
  392. }
  393.  
  394. BOOL AFXAPI AfxOleUnregisterServerClass(
  395.     REFCLSID clsid, LPCTSTR lpszClassName, LPCTSTR lpszShortTypeName,
  396.     LPCTSTR lpszLongTypeName, OLE_APPTYPE nAppType, LPCTSTR* rglpszRegister,
  397.     LPCTSTR* rglpszOverwrite)
  398. {
  399.     // use standard registration entries if non given
  400.     if (rglpszRegister == NULL)
  401.         rglpszRegister = (LPCTSTR*)rgStdEntries[nAppType].rglpszRegister;
  402.     if (rglpszOverwrite == NULL)
  403.     {
  404.         // DLL contexts have special strings
  405.         if (!afxContextIsDLL)
  406.             rglpszOverwrite = (LPCTSTR*)rgStdEntries[nAppType].rglpszOverwrite;
  407.         else
  408.             rglpszOverwrite = (LPCTSTR*)rgStdEntriesDLL[nAppType].rglpszOverwrite;
  409.     }
  410.  
  411.     CAfxOleSymbolTable table(NUM_REG_VARS);
  412.  
  413.     if (!_AfxOleMakeSymbolTable(table, clsid, lpszClassName,
  414.                 lpszShortTypeName, lpszLongTypeName, 0, NULL, NULL))
  415.     {
  416.         return FALSE;
  417.     }
  418.  
  419.     // clean up the the registry with helper function
  420.     BOOL bResult;
  421.     bResult = AfxOleUnregisterHelper(rglpszRegister, table.GetArray(),
  422.         NUM_REG_VARS);
  423.     if (bResult && rglpszOverwrite != NULL)
  424.     {
  425.         bResult = AfxOleUnregisterHelper(rglpszOverwrite, table.GetArray(),
  426.             NUM_REG_VARS);
  427.     }
  428.  
  429.     return bResult;
  430. }
  431.  
  432. // removes key/value pairs from system registry
  433. BOOL AFXAPI AfxOleUnregisterHelper(LPCTSTR const* rglpszRegister,
  434.     LPCTSTR const* rglpszSymbols, int nSymbols,
  435.     HKEY hKeyRoot /* = HKEY_CLASSES_ROOT */)
  436. {
  437.     ASSERT(rglpszRegister != NULL);
  438.     ASSERT(nSymbols == 0 || rglpszSymbols != NULL);
  439.  
  440.     CString strKey;
  441.     CString strValue;
  442.  
  443.     // keeping a key open makes this go a bit faster
  444.     HKEY hKeyTemp = NULL;
  445.     if (hKeyRoot == HKEY_CLASSES_ROOT)
  446.         WCE_FCTN(RegOpenKey(HKEY_CLASSES_ROOT, _T("CLSID"), &hKeyTemp));
  447.  
  448.     BOOL bResult = TRUE;
  449.     while (*rglpszRegister != NULL)
  450.     {
  451.         LPCTSTR lpszKey = *rglpszRegister++;
  452.         if ((hKeyRoot == HKEY_CLASSES_ROOT) && (*lpszKey == '\0'))
  453.             continue;
  454.  
  455.         AfxFormatStrings(strKey, lpszKey, rglpszSymbols, nSymbols);
  456.  
  457.         if ((hKeyRoot == HKEY_CLASSES_ROOT) && strKey.IsEmpty())
  458.         {
  459.             TRACE1("Warning: skipping empty key '%s'.\n", lpszKey);
  460.             continue;
  461.         }
  462.  
  463.         _AfxDeleteRegKey(strKey);
  464.     }
  465.  
  466.     if (hKeyTemp != NULL)
  467.         RegCloseKey(hKeyTemp);
  468.  
  469.     return bResult;
  470. }
  471.  
  472. // writes key/value pairs to system registry
  473. BOOL AFXAPI AfxOleRegisterHelper(LPCTSTR const* rglpszRegister,
  474.     LPCTSTR const* rglpszSymbols, int nSymbols, BOOL bReplace,
  475.     HKEY hKeyRoot /* = HKEY_CLASSES_ROOT */)
  476. {
  477.     ASSERT(rglpszRegister != NULL);
  478.     ASSERT(nSymbols == 0 || rglpszSymbols != NULL);
  479.  
  480.     CString strKey;
  481.     CString strValue;
  482.  
  483.     // keeping a key open makes this go a bit faster
  484.     HKEY hKeyTemp = NULL;
  485.     if (hKeyRoot == HKEY_CLASSES_ROOT)
  486.         WCE_FCTN(RegOpenKey)(HKEY_CLASSES_ROOT, _T("CLSID"), &hKeyTemp);
  487.  
  488.     BOOL bResult = TRUE;
  489.     while (*rglpszRegister != NULL)
  490.     {
  491.         LPCTSTR lpszKey = *rglpszRegister++;
  492.         if ((hKeyRoot == HKEY_CLASSES_ROOT) && (*lpszKey == '\0'))
  493.             continue;
  494.  
  495.         LPCTSTR lpszValue = lpszKey + lstrlen(lpszKey) + 1;
  496.  
  497.         AfxFormatStrings(strKey, lpszKey, rglpszSymbols, nSymbols);
  498.         AfxFormatStrings(strValue, lpszValue, rglpszSymbols, nSymbols);
  499.  
  500.         if ((hKeyRoot == HKEY_CLASSES_ROOT) && strKey.IsEmpty())
  501.         {
  502.             TRACE1("Warning: skipping empty key '%s'.\n", lpszKey);
  503.             continue;
  504.         }
  505.  
  506.         if (!bReplace)
  507.         {
  508.             TCHAR szBuffer[256];
  509.             LONG lSize = sizeof(szBuffer);
  510.             if (::WCE_FCTN(RegQueryValue)(hKeyRoot, strKey, szBuffer, &lSize) ==
  511.                 ERROR_SUCCESS)
  512.             {
  513. #ifdef _DEBUG
  514.                 if (strValue != szBuffer)
  515.                 {
  516.                     TRACE2("Warning: Leaving value '%s' for key '%s' in registry\n",
  517.                         szBuffer, (LPCTSTR)strKey);
  518.                     TRACE1("\tintended value was '%s'.\n", (LPCTSTR)strValue);
  519.                 }
  520. #endif
  521.                 continue;
  522.             }
  523.         }
  524.  
  525.         if (::WCE_FCTN(RegSetValue)(hKeyRoot, strKey, REG_SZ, strValue, lstrlen(strValue) * sizeof(TCHAR))
  526.             != ERROR_SUCCESS)
  527.         {
  528.             TRACE2("Error: failed setting key '%s' to value '%s'.\n",
  529.                 (LPCTSTR)strKey, (LPCTSTR)strValue);
  530.             bResult = FALSE;
  531.             break;
  532.         }
  533.     }
  534.  
  535.     if (hKeyTemp != NULL)
  536.         RegCloseKey(hKeyTemp);
  537.  
  538.     return bResult;
  539. }
  540.  
  541. /////////////////////////////////////////////////////////////////////////////
  542.